/**
 * @file
 * @author  Tsin Smith <tsin.creator@gmail.com>
 *
 */

#ifndef __TSIN_UTIL_LOGGER_HPP__
#define __TSIN_UTIL_LOGGER_HPP__

#include <tsin/util/common.hpp>

namespace tsin {

        /**
         * @class Logger
         * @ingroup util
         * @brief Interface for logging.
         */
        class UTIL_DLLEXPORT Logger
        {
        public:
                enum LogLevel {
                        BUG = 0,
                        ALERT,
                        WARNING,
                        INFO,
                        DEBUG,
                        ALL,
                        CONTINUE = 100,
                };

                Logger();

                /**
                 * Set the level for coming logs.
                 *
                 * @param level The level of the coming logs.
                 *
                 * @return This logger itself.
                 */
                virtual Logger &setLogLevel(LogLevel level);

                /**
                 * Set the filter level for coming logs.
                 *
                 * If the coming logs' level is lower than the filter, they'll not be printed.
                 *
                 * @param level The filter level.
                 */
                virtual void setFilterLevel(LogLevel level);

                virtual Logger &operator<<(const int i) = 0;
                virtual Logger &operator<<(const char *str) = 0;
                virtual Logger &operator<<(const float d) = 0;

        protected:
                LogLevel current, filter;

        private:
                static const char *logLevelString[ALL];
        };

        extern UTIL_DLLEXPORT Logger *logp;

}

#define tsinlog(LEVEL) ((*logp).setLogLevel(Logger::LEVEL))
#define tbug tsinlog(BUG)
#define talert tsinlog(ALERT)
#define twarn tsinlog(WARNING)
#define tinfo tsinlog(INFO)
#define tdebug tsinlog(DEBUG)
#define tcont tsinlog(CONTINUE)

#endif /* __TSIN_UTIL_LOGGER_HPP__ */
